#pragma once
#include <map>
#include <set>
#include <list>
#include "Command.h"

namespace bs
{
	/*
	  optimize: because the command is a little object, so it can config
	  an object pool to manage the new and delete of the cmds, this can decrease
	  the memory fragment, improve the app speed(only in the case that cmds are used much more)
	*/

	class CommandDispatcher
	{
	public:
		CommandDispatcher();
		~CommandDispatcher();

		static CommandDispatcher& Instance();

		void RegisterCommandType(int type);
		void RegisterProcessor(int type, ICommandProcessor* processor);
		void UnregisterCommandType(int type);
		void UnregisterProcessor(int type, ICommandProcessor* processor);
		void UnregisterProcessor(ICommandProcessor* processor);

		void SendCommand(Command* cmd);      // the cmd will automatically delete
		void PostCommand(Command* cmd);      // the cmd will automatically delete

		void Dispatch();

	private:
		typedef std::set<ICommandProcessor*> ProcessorSet;
		typedef std::map<int, ProcessorSet*> ProcessorSetMap;

		ProcessorSetMap processors;
		std::list<Command*> commands;
	};

}
